#import <stdio.h>
#import <strings.h>
#import <streams/streams.h>
#import <appkit/NXImage.h>
#import <appkit/NXBitmapImageRep.h>
#import <appkit/View.h>
#import <appkit/Box.h>
#import <appkit/Cell.h>
#import <appkit/PopUpList.h>
#import <appkit/Button.h>
#import <appkit/TextField.h>
#import <appkit/Text.h>
#import <appkit/graphics.h>
#import <appkit/tiff.h>
#import "tiff.h"

@implementation TIFF

	id		myPopUp;					// Pop up list for compression.
	id		myTextIII;					// Will hold compression factor.
	int		compression;					// Compression method to use.
	float		factor;						// Factor to compress by.

- init
{
	compression = NX_TIFF_COMPRESSION_NONE;
	factor = 10.0;
	
#ifdef DEBUG
	fprintf(stderr, "Tiff module initialized\n");
#endif
	
	return self;
}

- free
{
	return self;
}

- readFromStream: (NXStream *)stream from: sender;
{
#ifdef DEBUG
	fprintf(stderr, "Made it to read\n");
#endif

	return [[NXBitmapImageRep alloc] initFromStream: stream];
}

- (BOOL)write: (id)image toStream: (NXStream *)stream from: sender;
{
	if ([image bitsPerSample] < 4) {
		if (compression == NX_TIFF_COMPRESSION_JPEG) {
			compression = NX_TIFF_COMPRESSION_LZW;
#ifdef DEBUG
			fprintf(stderr, "Compress dropped from JPEG to LZH\n");
#endif
		}
	}
#ifdef DEBUG
	fprintf(stderr, "compression %d and factor %.2f\n", compression, factor);
#endif
	[image 	writeTIFF: stream 
			usingCompression: compression
			andFactor: factor];

	return YES;
}

- popClick
{
	const char		*selection;
	
	selection = [myPopUp selectedItem];
	if (!strcmp(selection, "None")) {
		compression = NX_TIFF_COMPRESSION_NONE;
	}
	else if (!strcmp(selection, "LZW")) {
		compression = NX_TIFF_COMPRESSION_LZW;
	}
	else if (!strcmp(selection, "Pack Bits")) {
		compression = NX_TIFF_COMPRESSION_PACKBITS;
	}
	else if (!strcmp(selection, "JPEG")) {
		compression = NX_TIFF_COMPRESSION_JPEG;
	}
#ifdef DEBUG
	fprintf(stderr, "Compress %s with factor %.2f\n", selection, factor);
#endif
	
	return self;
}

- readAllFromStream: (NXStream *)stream from: sender
{
#ifdef DEBUG
	fprintf(stderr, "Made it to read multiple\n");
#endif

	return [[NXImage alloc] initFromStream: stream];
}

- (BOOL)writeAll: (id)image toStream: (NXStream *)stream
{
#ifdef DEBUG
	fprintf(stderr, "Made it to write multiple\n");
#endif
	
	[image writeTIFF: stream allRepresentations: YES];

	return YES;
}

- customSaveView: (int)width
{
	id		myBox		= [Box alloc];
	id		myView		= [View alloc];
	id		myButton 	= [Button alloc];
	id		myText		= [TextField alloc];
	id		myTextII		= [TextField alloc];
	NXRect	myViewRect 	= {0, 0, width - 10, 30 };
	NXRect	myButRect 	= {width - 185, 5,   80, 21 };
	NXRect	myTextRect 	= {4, 6, width - 195, 18 };
	NXRect	myTextRectII = {width - 105, 6, 45, 18 };
	NXRect	myTextRectIII = {width - 55, 5, 40, 21 };

	[myBox initFrame: &myViewRect];
		
	[myView initFrame: &myViewRect];

	myPopUp  = [PopUpList alloc];
	[myPopUp init];
	[myPopUp addItem: "None"];
	[myPopUp addItem: "LZW"];
	[myPopUp addItem: "Pack Bits"];
	[myPopUp addItem: "JPEG"];
	[myPopUp setAction: @selector(popClick)];
	[myPopUp setTarget: self];

	[myButton initFrame: &myButRect];
	NXAttachPopUpList(myButton, myPopUp);
	[myView addSubview: myButton];
	[myButton setTitle: "None"];

	[myText initFrame: &myTextRect];
	[myText setEditable: NO];
	[myText setStringValue: "Compression"];
	[myText setBezeled: NO];
	[myText setAlignment: NX_RIGHTALIGNED];
	[myText setBackgroundGray: NX_LTGRAY];
	[myView addSubview: myText];

	[myTextII initFrame: &myTextRectII];
	[myTextII setEditable: NO];
	[myTextII setStringValue: "Factor"];
	[myTextII setBezeled: NO];
	[myTextII setAlignment: NX_RIGHTALIGNED];
	[myTextII setBackgroundGray: NX_LTGRAY];
	[myView addSubview: myTextII];

	myTextIII = [TextField alloc];
	[myTextIII initFrame: &myTextRectIII];
	[myTextIII setEditable: YES];
	[myTextIII setFloatValue: factor];
	[myTextIII setFloatingPointFormat: NO left: 0 right: 2];
	[myTextIII setBezeled: YES];
	[myTextIII setAlignment: NX_CENTERED];
	[myTextIII setBackgroundGray: NX_WHITE];
	[myTextIII  setTextDelegate: self];
	[myView addSubview: myTextIII];

	[myBox setContentView: myView];
	[myBox setTitle: "TIFF Options"];
	[myBox sizeToFit];

	return myBox;
}

- customOpenView: (int)width
{
	return nil;
}

- (char *)getFormatName
{
	return("Tagged Image File Format (TIFF)");
}

- textDidEnd: textObject endChar: (unsigned short)whyEnd
{
	factor = [myTextIII floatValue];
	if (factor < 1.0) factor = 1.0;
	if (factor > 255.0) factor = 255.0;

	[myTextIII setFloatValue: factor];

#ifdef DEBUG
	fprintf(stderr, "Editing ended\n");
#endif
	return self;
}

- (BOOL)setCustomParameter: (const char *)parameter withValue: (void *)ptr
{
	if (!strcmp(parameter,  TIFF_COMPRESS_METHOD)) {
		compression = *(int *)ptr;
		return YES;
	}
	else if (!strcmp(parameter, TIFF_COMPRESS_RATIO)) {
		float		tmpFactor;
		
		tmpFactor = *(float *)ptr;
		if ((tmpFactor < 1.0) || (tmpFactor > 255.0)) return NO;
		factor = tmpFactor;
		return YES;
	}
	else {
		return NO;
	}
}

- (void *)getCustomParameter: (const char *)parameter
{
	if (!strcmp(parameter,  TIFF_COMPRESS_METHOD)) {
		return &compression;
	}
	else if (!strcmp(parameter, TIFF_COMPRESS_RATIO)) {
		return &factor;
	}
	else {
		return nil;
	}
}

- (char *)copyrightNotice
{
	return "TIFF Converter\nby Alex Raftis\nCopyright (c) 1991 Cal Poly State University\nCopyright (c) 1986-1991 NeXT Computer Inc.\nEmail bugs to alex@data.ACS.CalPoly.EDU";
}
 
- (int)errorState
{
	return CONVERT_ERR_NONE;
}
 
- (int)errorMessage
{
	return ERROR_NO_ERROR;
}

- (char *)errorStringMessage
{
	return NULL;
}
 
- (BOOL)needsWindowServer;
{
	return NO;
}

- (char *)protocolVersion
{
	return "1.0";
}

@end
